-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[MLIR][SPIRV-TO-LLVM] Support SPV_INTEL_split_barrier ops #116648
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MLIR][SPIRV-TO-LLVM] Support SPV_INTEL_split_barrier ops #116648
Conversation
Add conversion to LLVM for `SPV_INTEL_split_barrier` operations via conversion to SPIR-V built-ins. Signed-off-by: Victor Perez <[email protected]>
|
@llvm/pr-subscribers-mlir-spirv @llvm/pr-subscribers-mlir Author: Victor Perez (victor-eds) ChangesAdd conversion to LLVM for Signed-off-by: Victor Perez <[email protected]> Full diff: https://github.com/llvm/llvm-project/pull/116648.diff 5 Files Affected:
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVIntelExtOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVIntelExtOps.td
index 8ff7d0d63469fd..82d26e365fb243 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVIntelExtOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVIntelExtOps.td
@@ -131,7 +131,7 @@ class SPIRV_IntelSplitBarrierOp<string mnemonic>
let results = (outs);
let assemblyFormat = [{
- $execution_scope `,` $memory_scope `,` $memory_semantics attr-dict
+ $execution_scope $memory_scope $memory_semantics attr-dict
}];
let hasVerifier = 0;
@@ -160,7 +160,7 @@ def SPIRV_INTELControlBarrierArriveOp
#### Example:
```mlir
- spirv.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
+ spirv.ControlBarrierArrive <Workgroup> <Device> <Acquire|UniformMemory>
```
}];
}
@@ -194,7 +194,7 @@ def SPIRV_INTELControlBarrierWaitOp
#### Example:
```mlir
- spirv.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
+ spirv.ControlBarrierWait <Workgroup> <Device> <Acquire|UniformMemory>
```
}];
}
diff --git a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
index ef0508e7ef5f0e..b11511f21d03d4 100644
--- a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
+++ b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
@@ -1057,17 +1057,21 @@ static LLVM::CallOp createSPIRVBuiltinCall(Location loc, OpBuilder &builder,
return call;
}
-class ControlBarrierPattern
- : public SPIRVToLLVMConversion<spirv::ControlBarrierOp> {
+template <typename BarrierOpTy>
+class ControlBarrierPattern : public SPIRVToLLVMConversion<BarrierOpTy> {
public:
- using SPIRVToLLVMConversion<spirv::ControlBarrierOp>::SPIRVToLLVMConversion;
+ using OpAdaptor = typename SPIRVToLLVMConversion<BarrierOpTy>::OpAdaptor;
+
+ using SPIRVToLLVMConversion<BarrierOpTy>::SPIRVToLLVMConversion;
+
+ static constexpr StringRef getFuncName();
LogicalResult
- matchAndRewrite(spirv::ControlBarrierOp controlBarrierOp, OpAdaptor adaptor,
+ matchAndRewrite(BarrierOpTy controlBarrierOp, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
- constexpr StringLiteral funcName = "_Z22__spirv_ControlBarrieriii";
+ constexpr StringRef funcName = getFuncName();
Operation *symbolTable =
- controlBarrierOp->getParentWithTrait<OpTrait::SymbolTable>();
+ controlBarrierOp->template getParentWithTrait<OpTrait::SymbolTable>();
Type i32 = rewriter.getI32Type();
@@ -1266,6 +1270,24 @@ class GroupReducePattern : public SPIRVToLLVMConversion<ReduceOp> {
}
};
+template <>
+constexpr StringRef
+ControlBarrierPattern<spirv::ControlBarrierOp>::getFuncName() {
+ return "_Z22__spirv_ControlBarrieriii";
+}
+
+template <>
+constexpr StringRef
+ControlBarrierPattern<spirv::INTELControlBarrierArriveOp>::getFuncName() {
+ return "_Z33__spirv_ControlBarrierArriveINTELiii";
+}
+
+template <>
+constexpr StringRef
+ControlBarrierPattern<spirv::INTELControlBarrierWaitOp>::getFuncName() {
+ return "_Z31__spirv_ControlBarrierWaitINTELiii";
+}
+
/// Converts `spirv.mlir.loop` to LLVM dialect. All blocks within selection
/// should be reachable for conversion to succeed. The structure of the loop in
/// LLVM dialect will be the following:
@@ -1899,7 +1921,9 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
ReturnPattern, ReturnValuePattern,
// Barrier ops
- ControlBarrierPattern,
+ ControlBarrierPattern<spirv::ControlBarrierOp>,
+ ControlBarrierPattern<spirv::INTELControlBarrierArriveOp>,
+ ControlBarrierPattern<spirv::INTELControlBarrierWaitOp>,
// Group reduction operations
GroupReducePattern<spirv::GroupIAddOp>,
diff --git a/mlir/test/Conversion/SPIRVToLLVM/barrier-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/barrier-ops-to-llvm.mlir
index d53afeeea15d10..359aa350ac90c6 100644
--- a/mlir/test/Conversion/SPIRVToLLVM/barrier-ops-to-llvm.mlir
+++ b/mlir/test/Conversion/SPIRVToLLVM/barrier-ops-to-llvm.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
+// RUN: mlir-opt -convert-spirv-to-llvm -split-input-file %s | FileCheck %s
//===----------------------------------------------------------------------===//
// spirv.ControlBarrierOp
@@ -21,3 +21,28 @@ spirv.func @control_barrier() "None" {
spirv.ControlBarrier <Workgroup>, <Workgroup>, <WorkgroupMemory>
spirv.Return
}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.INTEL.SplitBarrier
+//===----------------------------------------------------------------------===//
+
+// CHECK-DAG: llvm.func spir_funccc @_Z33__spirv_ControlBarrierArriveINTELiii(i32, i32, i32) attributes {convergent, no_unwind, will_return}
+// CHECK-DAG: llvm.func spir_funccc @_Z31__spirv_ControlBarrierWaitINTELiii(i32, i32, i32) attributes {convergent, no_unwind, will_return}
+
+// CHECK-LABEL: @split_barrier
+spirv.func @split_barrier() "None" {
+ // CHECK: [[EXECUTION:%.*]] = llvm.mlir.constant(2 : i32) : i32
+ // CHECK: [[MEMORY:%.*]] = llvm.mlir.constant(2 : i32) : i32
+ // CHECK: [[SEMANTICS:%.*]] = llvm.mlir.constant(768 : i32) : i32
+ // CHECK: llvm.call spir_funccc @_Z33__spirv_ControlBarrierArriveINTELiii([[EXECUTION]], [[MEMORY]], [[SEMANTICS]]) {convergent, no_unwind, will_return} : (i32, i32, i32) -> ()
+ spirv.INTEL.ControlBarrierArrive <Workgroup> <Workgroup> <CrossWorkgroupMemory|WorkgroupMemory>
+
+ // CHECK: [[EXECUTION:%.*]] = llvm.mlir.constant(2 : i32) : i32
+ // CHECK: [[MEMORY:%.*]] = llvm.mlir.constant(2 : i32) : i32
+ // CHECK: [[SEMANTICS:%.*]] = llvm.mlir.constant(256 : i32) : i32
+ // CHECK: llvm.call spir_funccc @_Z31__spirv_ControlBarrierWaitINTELiii([[EXECUTION]], [[MEMORY]], [[SEMANTICS]]) {convergent, no_unwind, will_return} : (i32, i32, i32) -> ()
+ spirv.INTEL.ControlBarrierWait <Workgroup> <Workgroup> <WorkgroupMemory>
+ spirv.Return
+}
diff --git a/mlir/test/Dialect/SPIRV/IR/intel-ext-ops.mlir b/mlir/test/Dialect/SPIRV/IR/intel-ext-ops.mlir
index 6dd0353d9374ad..bb15d018a6c448 100644
--- a/mlir/test/Dialect/SPIRV/IR/intel-ext-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/intel-ext-ops.mlir
@@ -77,10 +77,10 @@ spirv.func @bf16_to_f32_vec_unsupported(%arg0 : vector<2xi16>) "None" {
//===----------------------------------------------------------------------===//
spirv.func @split_barrier() "None" {
- // CHECK: spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
- spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
- // CHECK: spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
- spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
+ // CHECK: spirv.INTEL.ControlBarrierArrive <Workgroup> <Device> <Acquire|UniformMemory>
+ spirv.INTEL.ControlBarrierArrive <Workgroup> <Device> <Acquire|UniformMemory>
+ // CHECK: spirv.INTEL.ControlBarrierWait <Workgroup> <Device> <Acquire|UniformMemory>
+ spirv.INTEL.ControlBarrierWait <Workgroup> <Device> <Acquire|UniformMemory>
spirv.Return
}
diff --git a/mlir/test/Target/SPIRV/intel-ext-ops.mlir b/mlir/test/Target/SPIRV/intel-ext-ops.mlir
index 8c50501cf7409d..6d2fd324363c62 100644
--- a/mlir/test/Target/SPIRV/intel-ext-ops.mlir
+++ b/mlir/test/Target/SPIRV/intel-ext-ops.mlir
@@ -40,10 +40,10 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Bfloat16ConversionINTEL]
spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [SplitBarrierINTEL], [SPV_INTEL_split_barrier]> {
// CHECK-LABEL: @split_barrier
spirv.func @split_barrier() "None" {
- // CHECK: spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
- spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
- // CHECK: spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
- spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
+ // CHECK: spirv.INTEL.ControlBarrierArrive <Workgroup> <Device> <Acquire|UniformMemory>
+ spirv.INTEL.ControlBarrierArrive <Workgroup> <Device> <Acquire|UniformMemory>
+ // CHECK: spirv.INTEL.ControlBarrierWait <Workgroup> <Device> <Acquire|UniformMemory>
+ spirv.INTEL.ControlBarrierWait <Workgroup> <Device> <Acquire|UniformMemory>
spirv.Return
}
}
|
8d98890 to
7e4331c
Compare
|
@kuhar can we get this merged before the PR dropping the commas that depends on this one? |
kuhar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure
|
I'd like to get this merged by tomorrow if @antiagainst has no comment. |
|
You can go ahead, Lei rarely reviews SPIR-V stuff recently |
…116673) Drop commas from split barrier operations assembly format. Signed-off-by: Victor Perez <[email protected]> Depends on #116648, review ec8d354 only. --------- Signed-off-by: Victor Perez <[email protected]>
Add conversion to LLVM for
SPV_INTEL_split_barrieroperations via conversion to SPIR-V built-ins.Signed-off-by: Victor Perez [email protected]